# Copyright 2010 Giacomo Alzetta
# This file is part of "LimberEditor" and is distribuhited under the
# terms of the MIT license.

import unittest

from limber import documentmanager
from mocks import *


class TestDocumentManager(unittest.TestCase):

    def setUp(self):
        self.parent = MockApplication()
        self.view_manager = MockViewManager()

    def testInstantiate(self):
        try:
            document_manager = documentmanager.DocumentManager(self.parent,  self.view_manager)
        except Exception, e:
            self.fail(str(e))

    def testCreateDocument(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)
        number_of_docs = document_manager.number_of_documents() + 1
        number_of_views = document_manager.number_of_views() + 1
        try:
            document = document_manager.create_document(MockDocument, MockView)
        except Exception, e:
            self.fail("Could not add a new document: %s" % str(e))

        self.assertTrue(bool(document),  'No document created.')
        self.assertEqual(number_of_docs,  document_manager.number_of_documents(),
                         'No document added.')
        self.assertEqual(number_of_views,  document_manager.number_of_views(),
                         'No view added.')
        self.assertTrue(bool(document_manager.views(document)),
                        'Document does not have a view.')

    def testAddView(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)
        document = document_manager.create_document(MockDocument, MockView)
        number_of_docs = document_manager.number_of_documents()
        number_of_views = document_manager.number_of_views() + 1
        number_of_doc_views = len(document_manager.views(document)) + 1

        try:
            view = document_manager.add_view(document, MockView)
        except documentmanager.DocumentManagerError, e:
            self.fail(str(e))
        except Exception, e:
            self.fail("Could not add a view to a document " + str(e))

        self.assertTrue(bool(view),  'No view created.')
        self.assertEqual(number_of_docs, document_manager.number_of_documents(),
                         'Document added')
        self.assertEqual(number_of_views, document_manager.number_of_views(),
                         'No view added')
        self.assertEqual(number_of_doc_views, len(document_manager.views(document)),
                         'No view added to document')

        view = None
        document = MockDocument()
        try:
            view = document_manager.add_view(document, MockView)
            self.fail('Should not have been able to add a view '
                      'to an unmanaged document')
        except documentmanager.DocumentManagerError, e:
            pass
        self.assertTrue(view is None, 'View created')

    def testAddDocument(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)
        document = MockDocument()

        try:
            view = document_manager.add_document(document, MockView)
        except Exception, e:
            self.fail('Could not add the existing document: %s' % e)

        self.assertTrue(bool(view), 'No view created.')
        self.assertEqual(1, document_manager.number_of_documents(),
                         'The document was not added.')
        self.assertEqual(1, document_manager.number_of_views(),
                         'No view added to the document.')

    def testActiveDocument(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)

        document = document_manager.create_document(MockDocument, MockView)
        self.assertTrue(document is document_manager.active_document(),
                        'Wrong active document.')

        document2 = document_manager.create_document(MockDocument, MockView)
        self.assertTrue(document2 is document_manager.active_document(),
                        'Creating a new document did not change the focus.')

    def testSaveDocument(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)

        document = document_manager.create_document(MockDocument, MockView)
        self.assertTrue(document_manager._save_document(document),
                        'Could not save the document.')

    def testQueryCloseDocument(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)

        document = document_manager.create_document(MockDocument, MockView)
        try:
            response = document_manager._query_close_document(document)
        except Exception, e:
            self.fail('Could not close the document: %s' % e)

        self.assertTrue(response, 'The document manager won\'t close the document.')

    def testRemoveView(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)

        document = document_manager.create_document(MockDocument, MockView)
        view2 = document_manager.add_view(document, MockView)

        try:
            document_manager._remove_view(document, view2)
        except Exception, e:
            self.fail('Could not remove the view:%s' % e)

        self.assertEqual(1, document_manager.number_of_views(),
                         'The view was not removed.')

        view3 = MockView(self.view_manager, None)
        try:
            document_manager._remove_view(document, view3)
            self.fail('Should not be able to remove an unmanaged view.')
        except documentmanager.DocumentManagerError:
            pass
        except Exception, e:
            self.fail('Error: %s' % e)

        document2 = document_manager.create_document(MockDocument, MockView)
        view4 = document_manager.views(document2)[0]
        try:
            document_manager._remove_view(document, view4)
            self.fail('Should not be able to remove a view of an other document.')
        except documentmanager.DocumentManagerError:
            pass
        except Exception, e:
            self.fail('Error: %s' % e)

    def testCloseView(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)

        document = document_manager.create_document(MockDocument, MockView)
        view2 = document_manager.add_view(document, MockView)

        response = False
        try:
            response = document_manager.close_view(view2)
        except Exception, e:
            self.fail('Could not close the view: %s' % e)

        self.assertTrue(response, 'The view was not removed or the return value is wrong.')
        self.assertEqual(1, document_manager.number_of_views(),
                         'The view was not closed.')

        response = False
        view3 = MockView(self.view_manager, None)
        try:
            response = document_manager.close_view(view3)
            self.fail('Should not be able to close an unmanaged view.')
        except documentmanager.DocumentManagerError:
            pass
        except Exception, e:
            self.fail('Error:%s' % e)

        self.assertFalse(bool(response), 'The view was closed or the return value is wrong.')
        self.assertEqual(1, document_manager.number_of_views(),
                         'A view was closed.')

        response = False
        try:
            response = document_manager.close_view(document_manager.views(document)[0])
        except Exception, e:
            self.fail('Could not close the view: %s' % e)

        self.assertTrue(response, 'Could not close the view or the return value is wrong.')
        self.assertFalse(bool(document_manager.number_of_views()),
                         'The view was not closed.')
        self.assertFalse(bool(document_manager.number_of_documents()),
                         'The document was not closed.')

    def testCloseDocument(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)

        document = document_manager.create_document(MockDocument, MockView)

        response = False
        try:
            response = document_manager.close_document(document)
        except Exception, e:
            self.fail('Could not close the document: %s' % e)

        self.assertTrue(response, 'Could not close the document or the return value if wrong.')
        self.assertEqual(0,  document_manager.number_of_documents(),
                         'The document was not closed.')
        self.assertEqual(0,  document_manager.number_of_views(),
                         'Not all views were closed.')

        response = False
        document2 = MockDocument()
        try:
            response = document_manager.close_document(document2)
            self.fail('Should not be able to close an unmanaged document.')
        except documentmanager.DocumentManagerError:
            pass
        except Exception, e:
            self.fail('Error: %s' % e)

        self.assertFalse(response, 'The document was removed or the return value is wrong.')

    def testCloseAllDocuments(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)

        document = document_manager.create_document(MockDocument, MockView)
        document2 = document_manager.create_document(MockDocument, MockView)

        try:
            response = document_manager.close_all_documents()
        except Exception, e:
            self.fail('Could not close all documents: %s' % e)

        self.assertTrue(response, 'Could not close all documents or return value is wrong.')
        self.assertEqual(0, document_manager.number_of_documents(),
                         'Not all documents closed.')
        self.assertEqual(0, document_manager.number_of_views(),
                         'Not all views removed.')
    
    def testModifiedDocuments(self):
        document_manager = documentmanager.DocumentManager(self.parent, self.view_manager)
        
        document = document_manager.create_document(MockDocumentWithDirty, MockView)
        document2 = document_manager.create_document(MockDocumentWithDirty, MockView)
        
        self.assertEqual(sorted(document_manager.modified_documents()),
                         sorted((document, document2)))
        document.set_modified(False)
        
        self.assertEqual(sorted(document_manager.modified_documents()),
                         sorted((document2,)))